﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
 
namespace Solidi
{
	sealed class CircularDependencyContext : DependencyContextDecorator, IDependencyResolver
	{
		private CircularDependencyContext _previous;
		private CircularDependency _dependency;
	
		public CircularDependencyContext(IDependencyContext context, IDependencyKey key, CircularDependencyContext previous)
			: base(context)
		{
			_dependency = new CircularDependency(key);

			_previous = previous;
		}

		public object Resolve(IDependencyContext context, IDependencyKey key)
		{
			CircularDependencyContext previous = this;

			while (previous != null)
			{
				CircularDependency dependency = previous._dependency;

				if (dependency.IsCircular(key))
				{
					object instance = dependency.ResolvePrevious(context);

					if (instance == null)
					{
						throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "Circular dependency in graph for key {0}.", key), "key");
					}
					else
					{
						return instance;
					}
				}

				previous = previous._previous;
			}

			context = new CircularDependencyContext(context, key, this);

			return base.Resolver.Resolve(context, key);
		}

		public bool Release(IDependencyContainer container, object instance)
		{
			return base.Resolver.Release(container, instance);
		}

		public override IDependencyResolver Resolver
		{
			get
			{
				return this;
			}
		}
	}
}
